package cn.itsource.wechat.service.imp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.pojo.domain.User;
import cn.itsource.org.pojo.vo.LoginInfo;
import cn.itsource.wechat.mapper.WxUserMapper;
import cn.itsource.wechat.pojo.domain.WxUser;
import cn.itsource.wechat.pojo.dto.BinderDto;
import cn.itsource.wechat.pojo.dto.WechartTokenDto;
import cn.itsource.wechat.pojo.dto.WechartUserInfoDto;
import cn.itsource.wechat.pojo.dto.WechatProperties;
import cn.itsource.wechat.service.IWeChatService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WeChatServiceImpl implements IWeChatService {

    @Autowired
    private WechatProperties wechatProperties;

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserMapper userMapper;


    @Override
    public String tologin() {
        /* 第一步*/

        //1.获取到yml中的地址值 含有%s
        String url = wechatProperties.getAuthorizationCodeUrl();
        System.out.println(url);

        //https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect
        //2.替换其中的%s
        url = String.format(url, wechatProperties.getAppId(), wechatProperties.getRedirectUri(), IdUtil.fastSimpleUUID());

        //3.重定向到url
        return "redirect:"+url;
    }

    @Override
    public String callback(String code) {

        /*第二步：通过code换取access_token*/
        //1.获取拿到token的url
        String tokenUrl = wechatProperties.getTokenUrl();

        //2.替换%s  拼接好了请求的url地址
        tokenUrl = String.format(tokenUrl, wechatProperties.getAppId(), wechatProperties.getAppSecrect(), code);

        //3.访问地址 get访问
        String tokenResult = HttpUtil.get(tokenUrl);

        //{"access_token":"64__7dkMsPq6Vqv7_ryxSpAxqTvzCJz6TclVzc5EGOUVXdkvs_nFRH2wI1BsK7pAwAiYWygfZBqFRri0vc9nKjJJ7RQnhHgCtuWfvCHC2wkyhA","expires_in":7200,"refresh_token":"64_9_zPkUax9nwlAEstIWGDAHghuMTuXqlAoZVM9T0-RQM3KrUe5ym43_mgcgm0Gs63duYWe81wu9xM5cGbEU6jAVQSy6BNN1BXHK4X2vZHqlg","openid":"oa9wA0w-gS7UBELaGnANDFrJJ7pM","scope":"snsapi_login","unionid":"ovnCWw0s9etOqshJwTaGO8r2RRP8"}
        System.out.println(tokenResult);

        //4.把返回的token结果json数据设置到对象中
        WechartTokenDto wechartTokenDto = JSONObject.parseObject(tokenResult, WechartTokenDto.class);

        System.out.println(wechartTokenDto);

        /*第三步：通过token拿到资源*/
        String userinfoUrl = wechatProperties.getUserinfoUrl();

        //%s
        userinfoUrl = String.format(userinfoUrl, wechartTokenDto.getAccess_token(), wechartTokenDto.getOpenid());
        System.out.println(userinfoUrl);

        //发送get请求
        String userInfoResult = HttpUtil.get(userinfoUrl);

        System.out.println(userInfoResult);

        //把json字符串转成对象
        WechartUserInfoDto infoDto = JSONObject.parseObject(userInfoResult, WechartUserInfoDto.class);

        System.out.println(infoDto);


        /**
         * if  openid查wxuser表没有数据
         *
         * 携带openid的方式
         * 跳转到http:localhost:8081/binder.html?openid=sdfdsfdslkfjdslkfj
         */

        /**-----------上面是微信三部曲 ，下面绑定的流程了，前面主要是提供openid，你在源码微信平台唯一标识----------------*/
        //情况1  新用户  t_wxuser没有数据 t_user不管有没有数据都没用
        //1.通过openid查询t_wxuser表，如果没查到，需要新增
        String openid = infoDto.getOpenid();
        WxUser dbWxUser = wxUserMapper.findByOpenid(openid);
        if (dbWxUser == null) {
            //1.1微信用户入库
            WxUser wxUser = BeanUtil.copyProperties(infoDto, WxUser.class);
            wxUserMapper.insertSelective(wxUser);

            //2.跳转到绑定页面，携带openid
            return "redirect:http://localhost:8081/binder.html?openid=" + openid;
        }

        //情况2 特别完整的情况， 走到这，wxuser查到了  判断完整的情况
        //1.dbWxUser拿到user_id外键，外键不能为null
        Long userId = dbWxUser.getUserId();
        //2.通过这个外键，查询user表
        if (userId != null){
            //3.user能查到，并且手机号存在
            User user = userMapper.selectByPrimaryKey(userId);

            if (user != null && StringUtils.isNotBlank(user.getPhone())){
                //4.存redis
                String token = IdUtil.fastSimpleUUID();

                LoginInfo loginInfo = BeanUtil.copyProperties(user, LoginInfo.class);
                loginInfo.setToken(token);
                loginInfo.setUserId(user.getId());

                redisService.setStringKeyAndValue(token,loginInfo,30);
                //5.跳转到登录页面
                return "redirect:http://localhost:8081/index.html?token=" + token + "&phone=" + user.getPhone();
            }
        }
        //其他情况
        return "redirect:http://localhost:8081/binder.html?openid=" + openid;
    }

    @Override
    public AjaxResult binder(BinderDto binderDto) {

        //从redis里面拿到code，去验证code ，省略  自己写

        //1.通过手机号，查询t_user表
        String phone = binderDto.getPhone();
        User byPhone = userMapper.findByPhone(phone);

        //2.如果没有查到 新增user对象，拿到userId
        Long userId = null;
        User resultUser = null;
        if (byPhone == null){
            User user = new User();
            user.setPhone(phone);
            user.setPassword("123456");
            //加密加盐
            user.init();
            userMapper.insertSelective(user);

            userId = user.getId();
            resultUser = user;
        }else {
            //3.如果查到了，要拿到userId
            userId = byPhone.getId();
            resultUser = byPhone;
        }

        //4.通过openid查询到t_wxuser对象
        String openid = binderDto.getOpenid();
        WxUser dbWxUser = wxUserMapper.findByOpenid(openid);

        //5.维护user_id，入库
        dbWxUser.setUserId(userId);
        wxUserMapper.updateByPrimaryKeySelective(dbWxUser);

        //6.存redis登录
        String token = IdUtil.fastSimpleUUID();

        LoginInfo loginInfo = BeanUtil.copyProperties(resultUser, LoginInfo.class);
        loginInfo.setToken(token);
        //设置userId的值
        loginInfo.setUserId(resultUser.getId());

        redisService.setStringKeyAndValue(token,loginInfo,30);

        //7.返回对象 ，携带token给回去，username
        return AjaxResult.createSuccess(loginInfo);
    }

    @Autowired
    private RedisService redisService;






    public static void main(String[] args) {
        String a = "我是%s,我%s岁了";

        String s = String.format(a, "王天霸", 16);

        System.out.println(s); //我是王天霸,我16岁了


    }
}
